
#include <bitserial_api.h>
#include <vmtypes.h>
#include <csrtypes.h>
#include <pio.h>
#include <panic.h>
#include <macros.h>
#include <pio_common.h>
#include <logging.h>
#include "zy_i2c.h"

#define I2C_ADDR_1787 0x28

#define PIOBANK(pio) ((uint16)((pio) / 32))
#define PIOMASK(pio) (1UL << ((pio) % 32))

#define SCL_PIN 60
#define SDA_PIN 15
#define SCL_KHz 400

static bitserial_config bsconfig;
void i2cPioInit(void)
{
    uint32 i;
    uint16 bank;
    uint32 mask;
    struct
    {
        uint16 pio;
        pin_function_id func;
    }i2c_pios[] = {
        {SCL_PIN, BITSERIAL_1_CLOCK_OUT},
        {SCL_PIN, BITSERIAL_1_CLOCK_IN},
        {SDA_PIN, BITSERIAL_1_DATA_OUT},
        {SDA_PIN, BITSERIAL_1_DATA_IN}};
    
    for (i = 0; i < ARRAY_DIM(i2c_pios); i++)
    {
        uint16 pio = i2c_pios[i].pio;
        bank = PIOBANK(pio);
        mask = PIOMASK(pio);

        PanicNotZero(PioSetMapPins32Bank(bank, mask, 0));
        PanicFalse(PioSetFunction(pio, i2c_pios[i].func));
        PanicNotZero(PioSetDir32Bank(bank, mask, 0));
        PanicNotZero(PioSet32Bank(bank, mask, mask));
        PanicNotZero(PioSetStrongBias32Bank(bank, mask, mask));
    }

    bsconfig.mode = BITSERIAL_MODE_I2C_MASTER;
    bsconfig.clock_frequency_khz = SCL_KHz;
    bsconfig.u.i2c_cfg.i2c_address = I2C_ADDR_1787;
    bsconfig.timeout_ms = 50;
}

bool i2c_write_byte(uint16 addr, uint8 *value, uint16 size)
{
    bitserial_result result;
    uint8 data[size + 2];
    bitserial_handle i2cHander = BitserialOpen((bitserial_block_index)BITSERIAL_BLOCK_1, &bsconfig);

    data[0] = (uint8)(addr >> 8) & 0xff;
    data[1] = (uint8)(addr)&0xff;
    memcpy(&data[2], value, size);
    result = BitserialWrite(i2cHander, BITSERIAL_NO_MSG, data, size+2, BITSERIAL_FLAG_BLOCK);
    BitserialClose(i2cHander);
    return (result == BITSERIAL_RESULT_SUCCESS);
}

bool i2c_read_byte(uint16 addr, uint8 *value, uint16 size)
{
    bitserial_result result;
    uint8 data[2];
    bitserial_handle i2cHander = BitserialOpen((bitserial_block_index)BITSERIAL_BLOCK_1, &bsconfig);

    data[0] = (uint8)(addr >> 8) & 0xff;
    data[1] = (uint8)(addr)&0xff;
    result = BitserialWrite(i2cHander, BITSERIAL_NO_MSG, data, 2, BITSERIAL_FLAG_BLOCK);
    if (result == BITSERIAL_RESULT_SUCCESS)
    {
        result = BitserialRead(i2cHander, BITSERIAL_NO_MSG, value, size, BITSERIAL_FLAG_BLOCK);
    }
    BitserialClose(i2cHander);
    return (result == BITSERIAL_RESULT_SUCCESS);
}
